#include<string>
#include<iostream>
#include<vector>
using namespace std;
typedef string elemType;
class Stack
{
public:
	Stack(int capacity = 0) :_top(0)
	{
		if (capacity)
		{
			_stack.reserve(capacity);
		}
	}
	virtual ~Stack(){ }
	int size() const
	{
		return _stack.size();
	}
	bool empty()const
	{
		return !top();
	}
	bool full()const
	{
		return size() >= _stack.max_size();
	}
	int top() const
	{
		return _top;
	}
	void print(ostream& os = cout)const;

	bool pop(elemType& elem);
	bool push(const elemType& elem);
	virtual bool peek(int, elemType&)
	{
		return false;
	}

protected:
	vector<elemType> _stack;
	int _top;
};

static ostream& operator<<(ostream& os, const Stack& rhs)
{
	rhs.print();
	return os;
}


bool Stack::pop(elemType& elem)
{
	if (empty())
	{
		return false;
	}
	elem = _stack[--_top];
	_stack.pop_back();
	return true;
}

bool Stack::push(const elemType& elem)
{
	if (full())
	{
		return false;
	}
	_stack.push_back(elem);
	++_top;
	return true;
}

void Stack::print(ostream& os)const
{
	vector<elemType>::const_reverse_iterator
		rit = _stack.rbegin(),
		rend = _stack.rend();

	os << "\n\t";
	while (rit != rend)
	{
		os << *rit++ << "\n\t";
	}
	os << endl;
}

class Peekback_Stack :public Stack
{
public:
	Peekback_Stack(int capacity = 0) :Stack(capacity){ }
	virtual bool peek(int index, elemType& elem);
};

bool Peekback_Stack::peek(int index, elemType& elem)
{
	if (empty())
	{
		return false;
	}
	if (index < 0 || index >= size())
	{
		return false;
	}
	elem = _stack[index];
	return true;
}

static void peek(Stack& st, int index)
{
	cout << endl;
	string t;
	if (st.peek(index, t))
	{
		cout << "peek: " << t;
	}
	else
	{
		cout << "peek failed!";
	}
	cout << endl;
}

int main()
{
	Stack st;
	string str;
	while (cin >> str && !st.full())
	{
		st.push(str);
	}
	cout << '\n' << "About to call peek() with Stack" << endl;
	peek(st, st.top() - 1);
	cout << st;

	Peekback_Stack pst;
	while (!st.empty())
	{
		string t;
		if (st.pop(t))
		{
			pst.push(t);
		}
	}

	cout << "About to call peek() with Peekback_Stack" << endl;
	peek(pst, pst.top() - 1);
	cout << pst;
}